package sa4

import javax.servlet.http._
import javax.servlet.ServletConfig
import scala.xml._
import scala.collection.JavaConversions._
import scala.util.matching.Regex
import org.squeryl.SessionFactory
import org.squeryl.Session
import org.squeryl.adapters.H2Adapter
import java.sql.Timestamp
import java.sql.Date
import org.squeryl.PrimitiveTypeMode._
import org.squeryl.KeyedEntity
import org.squeryl.dsl.ast.LogicalBoolean
import org.squeryl.annotations.OptionType


class User(val surname: String, val lastName: String, val Email: String) extends KeyedEntity[Long] {
  val id = 0L
  def this() = this("", "", "")
}

// The database schema
  object Schema extends org.squeryl.Schema {
    val users = table[User]
    on(users)(user => declare(
      user.Email is (unique)))
  }
  

class SimpleServlet extends HttpServlet {
  override def init(config: ServletConfig) {
    Class.forName("org.h2.Driver")

    SessionFactory.concreteFactory = Some(() =>
      Session.create(
        java.sql.DriverManager.getConnection("jdbc:h2:" + System.getProperty("user.dir") + "/test"),
        new H2Adapter))

    // Recreate the database

    transaction {
       Schema.drop
    }

    transaction {
       Schema.create
    }

    	populate
    	populate1

  }

  def populate = transaction {

    val teacher=Schema.users.insert(new User("Nate", "Nystrom", "nate.nystrom@usi.ch"))
    val teaching_assistence1 = Schema.users.insert(new User("Saeed", "Aghaee", "saeed.aghaee@usi.ch"))
    val teaching_assistence2= Schema.users.insert(new User("Konstantin", "Rubinov", "rubinovk@usi.ch"))
    val student1 =Schema.users.insert(new User("Mona", "Esmaeili", "mona.esmaili@gmail.com"))
    val student2 =Schema.users.insert(new User("Simone", "D`Avico", "simodavi91@hotmail.it"))
    val student3=Schema.users.insert(new User("Nicola", "Zirman", "zimerman@usi.ch"))
    val student4=Schema.users.insert(new User("Daniel", "Gili","hellmaster_91@hotmail.it"))
    
    	  //Test Remove
//        removeuser(student2)

  }
  
   def populate1(name: String, mail: String, pass: String)=transaction{
  Schema.users.insert(new User(name,mail,pass))
 
  }
   
   
   def populate1=transaction{
    
    updatesurname("Mona","Tom")
    updateslastname("Esmaeili","schiller")
//    removeuser(student2)
  }

   def updatesurname(oldname:String,newname:String)=
        update(Schema.users)(n => where(n.surname === oldname)
        set(n.surname := newname))
        
   
   def updateslastname(oldlastname:String,newlastname:String)=
        update(Schema.users)(n => where(n.lastName === oldlastname)
        set(n.lastName := newlastname))    
         
      
   def updatesEmail(oldemail:String,newemail:String)=
        update(Schema.users)(n => where(n.lastName === oldemail)
        set(n.Email := newemail))   
    
        
   
       
    // delete.
  def removeuser(user:User) =
    Schema.users.deleteWhere(toBeDeleted => toBeDeleted.Email === user.Email)     

 def write(resp: HttpServletResponse, ns: NodeSeq) = resp.getWriter.write(new PrettyPrinter(72, 2).formatNodes(ns))

 override def service(req: HttpServletRequest, resp: HttpServletResponse) {
    val info = "^/(\\w+)$".r
    req.getRequestURI match {
//       case info(name) =>
//        write(resp, infoPage(name))
//     
//      case "o"
//      		routeTable("/") = makeForm _
      case "/" =>
        write(resp, listPage)
      case _ =>
        resp.sendError(HttpServletResponse.SC_NOT_FOUND)
    }
    
//     def makeForm(req: HttpServletRequest, resp: HttpServletResponse) {
//    val xml = renderPage
//    val html = prepareForm(xml)
//    resp.getWriter.write(new PrettyPrinter(72, 2).formatNodes(html))
  
  }
   
// def prepareForm(template: NodeSeq): NodeSeq = {
//    // Ugh. XML transformations in Scala are horrendous.
//    import scala.xml.transform._
//    import scala.xml.Null // hide scala.Null
//    object MakeForm extends RewriteRule {
//      override def transform(n: Node): Seq[Node] = n match {
//        case form: Elem if form.label == "form" =>
//          val Some(handler) = form.attribute("handler")
//          
//          // Make the handler and install in routeTable
//          val (uri, f) = makeHandler(handler.text)
//          routeTable(uri) = f
//          
//          // Add an action to the form.
//          form % Attribute(None, "action", Text(uri), Null)
//        case n => n
//      }
//    }
//    
//    def makeHandler(s: String): (String, HandlerFunction) = {
//    // Parse the handler string.
//    val q = "^(\\w+)\\((.*)\\)$".r
//
//    val (methodName, argNames) = s match {
//      case q(methodName, argNames) => (methodName, argNames.split(",").map(_.trim))
//      case _ => throw new RuntimeException("bad handler: " + s)
//    }
//
//    template.map(ns => new RuleTransformer(MakeForm)(ns))
//  }

  def info(s: User, recurse: Boolean): NodeSeq = {
    <dl>
      <dt>Surname:</dt>
      <dd>
        { s.surname }
      </dd>
      <dt>LastName:</dt>
      <dd>
        { s.lastName }
      </dd>
      <dt>Email:</dt>
      <dd>
        {s.Email}
      </dd>
     

    </dl>
        
//        {
//          if (recurse) {
//            <dl>
//              {
//                for (t <- s.satellites)
//                  yield <dt>{ t.rank }. { t.name }</dt><dd> { info(t, false) }</dd>
//              }
//            </dl>
//          } else {
//            <span>{ s.satellites.size }</span>
//          }
//        }
//      </dd>
//    </dl>

  }



  def infoPage(surname: String): NodeSeq = {
    <html>
      <head>
        <title>Results for {surname}</title>
      </head>
      <body>
       <h3>{surname}</h3>
      
        {
          transaction {
            for (a <- from(Schema.users)(a => where(a.surname === surname) select (a))) yield {
            	<div>
                 <h3>Information on { a.surname }</h3>
                {
                  info(a, true)
                }
              </div>  
            }
          }
        }
       </body>
    </html>
  }

def post = {
    <html>
      <head>
        <title>Form example</title>
      </head>
      <body>
        <h3>Post a comment</h3>
        <form method="post" handler="postComment(author, content)">
          <p>
            <span>Your name: </span>
            <input type="text" name="author"/>
          </p>
          <p>
            <span>Your message: </span>
            <textarea name="content"></textarea>
          </p>
          <p>
            <input type="submit" value="Submit your comment"/>
          </p>
        </form>
      </body>
    </html>
  }
  
//  def form= {
//  <html>
 //     <head>
 //       <title>Form example</title>
//      </head>
 //     <body>
  //      <h3>Post a comment</h3>
  //      <form method="post" handler="post(surname,lastname,email)">
 //                       <p>
 //                       <span>Surname: </span>
 //           <input type="text" name="surname"/>
//                        </p>
 //               <p>
 //           <span>LastName: </span>
 //           <input type="text" name="lastname"/>
//                    </p>
 //           <p>
//            <span>Email: </span>
 //           <input type="text" name="email"/>
 //           </p>
//            <p>
 //           <input type="submit" value="Submit your comment"/>
 //           </p>
 //       </form>
 //     </body>
 //   </html>

//}
// 
// def post(surname: String, lastname: String , email:String) =
//    <html>
//      <head>
//        <title>Form submitted</title>
//      </head>
//      <body>
 //       <h3>Form submitted</h3>
 //       <p>{surname} submitted the following comment:</p>
//        <p>{lastname} submitted the following comment:</p>
//                <p>{email} submitted the following comment:</p>
 //     </body>
 //   </html>
//}


  def listPage = {
    <html>
      <head>
         <title>List all objects</title>
      </head>
      <body>
        <h3>All objects</h3>

        <dl>
          {
            transaction {
              for (s <- Schema.users)
                yield <dt>{ s.surname }</dt>
                      <dd>
                        { info(s, false) }
                      </dd>}}
        </dl>
      </body>
    </html>
  }
}